package com.example.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.User;
import com.example.exception.CustomException;
import com.example.service.LogService;
import com.example.service.UserService;
import com.example.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;

import static com.baomidou.mybatisplus.extension.toolkit.Db.getOne;

@RestController
@RequestMapping("/user")
@Api(tags = "用户相关接口",value = "用户相关接口")
public class UserController {

    @Autowired
    @Lazy
    private UserService userService;

    @Autowired
    private LogService logService;
    @Autowired
    private HttpServletRequest request;

    @ApiOperation(value = "根据token获取当前用户信息")
    public User getUser() {
        String token = request.getHeader("Authorization");
        String username = JwtUtil.getUsername(token);
        return userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username));
    }



    /**
     * 登录
     *
     * @param user
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "用户登陆")
    public Result<User> login(@RequestBody User user) {
        User one = userService.login(user);
        if (one != null) {
            return Result.success(one);
        }else
            return Result.error("1","账号或密码错误");
    }

    /**
     * 注册
     *
     * @param user
     * @return
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册")
    public Result<User> register(@RequestBody User user) {
        if (user.getPassword() == null) {
            user.setPassword("123456");
        }
        User dbUser = userService.register(user);
        logService.log(StrUtil.format("用户 {} 注册账号成功", user.getUsername()));
        return Result.success(dbUser);
    }
    /**
     * 异步检验用户名是否存在
     */
    @GetMapping("/checkName")
    @ApiOperation(value = "检验用户名是否存在")
    public Result<Boolean> checkNameExists(@RequestParam String username) {
        Boolean exists = userService.checkNameExists(username);
        return Result.success(exists);
    }

    @GetMapping("/refreshToken")
    @ApiOperation(value = "刷新用户token")
    public Result<String> refreshToken() throws Exception {
        return Result.success(JwtUtil.refreshToken(request.getHeader("Authorization")));
    }

    @PostMapping
    @ApiOperation(value = "新增用户")
    public Result<?> save(@RequestBody User user) {
        if (user.getPassword() == null) {
            user.setPassword("123456");
        }
        logService.log(StrUtil.format("新增用户：{} ", user.getUsername()));
        return Result.success(userService.save(user));
    }

    @PutMapping("/reset")
    @ApiOperation(value = "用户重置密码")
    public Result<?> reset(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPhone())
                || StrUtil.isBlank(user.getPassword())) {
            throw new CustomException("-1", "参数错误");
        }
        logService.log(StrUtil.format("{} 用户重置密码", user.getUsername()));
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", user.getUsername());
        queryWrapper.eq("phone", user.getPhone());
        User one = userService.getOne(queryWrapper);
        if (one == null) {
            throw new CustomException("-1", "未找到用户");
        }
        //给用户密码进行MD5三次迭代加密
        String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
        String hashedPassword = new SimpleHash("md5", user.getPassword(), salt, 3).toString();
        one.setPassword(hashedPassword);
        one.setSalt(salt);

//        one.setPassword(user.getPassword());
        return Result.success(userService.updateById(one));
    }

    @PutMapping
    @ApiOperation(value = "更新用户")
    public Result<?> update(@RequestBody User user) {
        logService.log(StrUtil.format("更新用户：{} ", user.getUsername()));
        if(user.getPassword() != null){
            String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
            String hashedPassword = new SimpleHash("md5", user.getPassword(), salt, 3).toString();
            user.setPassword(hashedPassword);
            user.setSalt(salt);
        }
        return Result.success(userService.updateById(user));
    }

    /**
     * 更新账户余额
     * @param money
     * @return
     */
    @PutMapping("/account/{money}")
    @ApiOperation(value = "更新账户余额")
    public Result<?> recharge(@PathVariable BigDecimal money) {
        User user = getUser();
        user.setAccount(user.getAccount().add(money));
        userService.updateById(user);
        logService.log(StrUtil.format("更新用户账户：{} ", user.getUsername()));
        return Result.success();
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "根据用户id删除用户")
    public Result<?> delete(@PathVariable Long id) {
        User user = userService.getById(id);
        logService.log(StrUtil.format("删除用户 {} ", user.getUsername()));
        userService.removeById(id);
        return Result.success();
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "根据用户id查找用户")
    public Result<User> findById(@PathVariable Long id) {
        User user = userService.findById(id);
        user.setPassword(null);
        user.setSalt(null);
        return Result.success(user);
    }

    @GetMapping
    @ApiOperation(value = "查找所有用户")
    public Result<List<User>> findAll() {
        return Result.success(userService.list());
    }

    @GetMapping("/page")
    @RequiresPermissions("2")
    public Result<IPage<User>> findPage(@RequestParam(required = false, defaultValue = "") String name,
                                        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                        @RequestParam(required = false, defaultValue = "10") Integer pageSize) throws Exception {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery().ne(User::getUsername, "admin").like(User::getUsername, name).orderByDesc(User::getId);
        return Result.success(userService.page(new Page<>(pageNum, pageSize), wrapper));
    }
}
